package com.gopay.common.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 该类提供ftp上传下载功能
 */
public class FtpUtil {
	private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);

	private static String encoding = System.getProperty("file.encoding");
	/**
	      * Description: 	向FTP服务器上传文件
	      * @param url		FTP服务器hostname
	      * @param port		FTP服务器端口
	      * @param uname		FTP登录账号
	      * @param pwd		FTP登录密码
	      * @param rtePath	FTP服务器保存目录,如果是根目录则为“/”
	      * @param rteFname 	上传到FTP服务器上的文件名
	      * @param locPath	本地文件路径
	      * @param locFname	本地文件名
	      * @return 			成功返回true，否则返回false
	      */
	public static boolean uploadFile(String url, int port, String uname, String pwd,
									 String rtePath, String rteFname, String locPath, String locFname, String encoding) {
		boolean result = false;
		InputStream input = null;
		FTPClient ftpClient = null;
		try {
			ftpClient = getFtpClient(url, uname, pwd, encoding, result);
			// 转移工作目录至指定目录下
			boolean change = ftpClient.changeWorkingDirectory(rtePath);
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
			if (change) {
				input = new FileInputStream(locPath + locFname);
				/*
				 * ftpClient.enterLocalPassiveMode(); 这个方法的意思就是每次数据连接之前，ftp
				 * client告诉ftp server开通一个端口来传输数据。 为什么要这样做呢，因为ftp
				 * server可能每次开启不同的端口来传输数据， 但是在linux上，由于安全限制，可能某些端口没有开启，所以就出现阻塞
				 */
				ftpClient.enterLocalPassiveMode();
				result = ftpClient.storeFile(new String(rteFname.getBytes(encoding),"iso-8859-1"), input);
				if (result) {
					logger.error(String.format("文件%s上传ftp成功!!!!!!!!!!!!", locFname));
				}
			}
			ftpClient.logout();
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("ftp上传失败！！！！！！！", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {ftpClient.disconnect();} catch (IOException ioe) {}
			}
			if (input != null) {
				try {input.close();} catch (IOException ioe) {}
			}
		}
		return result;
	}

	private static FTPClient getFtpClient(String url, String uname, String pwd,
										  String encoding, boolean result) throws SocketException, IOException {
		FTPClient ftpClient = new FTPClient();
		int reply;
		// 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
		ftpClient.connect(url);
		// ftp.connect(url, port);// 连接FTP服务器
		// 登录
		ftpClient.login(uname, pwd);
		ftpClient.setControlEncoding(encoding);
		ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
		// 检验是否连接成功
		reply = ftpClient.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			logger.error("ftp连接失败!!!!!!!!!!!!");
			ftpClient.disconnect();
			return null;
		}
		logger.error(url + ": ftp连接成功!!!!!!!!!!!!");
		return ftpClient;
	}

	/**
	 * Description: 		从FTP服务器下载文件
	      * @param url			FTP服务器hostname
	      * @param port			FTP服务器端口
	      * @param username		FTP登录账号
	      * @param password		FTP登录密码
	      * @param remotePath	FTP服务器上的相对路径
	      * @param fileName		要下载的文件名
	      * @param localPath		下载后保存到本地的路径
	      * @return
	      */
	public static boolean downFile(String url, int port, String uname, String pwd,
								   String rtePath, String rteFname, String locPath, String locFname, String encoding) {
		boolean result = false;
		OutputStream out = null;
		FTPClient ftpClient = null;
		try {
//			int reply;
//			ftpClient.setControlEncoding(encoding);
//
//			ftpClient.connect(url, port);
//			// 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
//			ftpClient.login(uname, pwd);// 登录
//			// 设置文件传输类型为二进制
//			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//			// 获取ftp登录应答代码
//			reply = ftpClient.getReplyCode();
//			// 验证是否登陆成功
//			if (!FTPReply.isPositiveCompletion(reply)) {
//				ftpClient.disconnect();
//				logger.error("FTP server refused connection.");
//				return result;
//			}
			ftpClient = getFtpClient(url, uname, pwd, encoding, result);
			// 转移到FTP服务器目录至指定的目录下
			ftpClient.changeWorkingDirectory(new String(rtePath.getBytes(encoding),"iso-8859-1"));
			ftpClient.enterLocalPassiveMode();
			// 获取文件列表
			FTPFile[] fs = ftpClient.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getName().equals(rteFname)) {
					out = new FileOutputStream((locPath.endsWith("/")?locPath:locPath+"/") + locFname);
					ftpClient.retrieveFile(ff.getName(), out);
				}
			}
			ftpClient.logout();
			result = true;
		} catch (IOException e) {
			logger.error("ftp下载失败！！！！！！！", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException ioe) {
					logger.error("FtpUtil.downFile disconnect error", ioe);
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException ioe) {
					logger.error("FtpUtil.downFile out.close error", ioe);
				}
			}
		}
		logger.error("ftp下载: " + rteFname + " " + result);
		return result;
	}

	/**
	 * Description: 		判断某目录下是否存在某文件
	      * @param url			FTP服务器hostname
	      * @param port			FTP服务器端口
	      * @param username		FTP登录账号
	      * @param password		FTP登录密码
	      * @param remotePath	FTP服务器上的相对路径
	      * @return
	      */
	public static boolean exist(String url, int port, String uname, String pwd, String rtePath, String rteFname, String encoding) {
		boolean result = false;
		FTPClient ftpClient = new FTPClient();
		try {
			ftpClient = getFtpClient(url, uname, pwd, encoding, result);
			ftpClient.changeWorkingDirectory(new String(rtePath.getBytes(encoding),"iso-8859-1"));
			ftpClient.enterLocalPassiveMode();
			// 获取文件列表
			FTPFile[] fs = ftpClient.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getName().equals(rteFname)) {
					result = true;
				}
			}
			ftpClient.logout();
		} catch (IOException e) {
			logger.error("查询文件是否存在失败！！！！！！！", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException ioe) {
					logger.error("FtpUtil.exist disconnect error", ioe);
				}
			}
		}
		logger.error("查询文件: " + rteFname + "是否存: " + result);
		return result;
	}


	public static void main(String[] args) {
//		boolean flag = FtpUtil.uploadFile("211.88.2.79", 21, "gfbmobilet","tFG6oGYR",
//				"cebliftpay", "testfile2222.txt", "/E:/", "testfile.txt","gbk");
//		System.out.println(flag);
//		boolean downFile = FtpUtil.downFile("211.88.2.79", 21, "gfbmobilet","tFG6oGYR",
//				"cebliftpay", "testfile.txt", "/E:", "testfile11112.txt","gbk");
//		System.out.println(downFile);
		boolean exist = FtpUtil.exist("211.88.2.79", 21, "gfbmobilet","tFG6oGYR",
				"cebliftpay", "test.txt", "gbk");
		System.out.println(exist);
	}
}
